/* 
 * File:   es.c
 * Author: FENG Xu <fengxu1989@gmail.com>
 *
 * Created on May 29, 2012, 5:47 PM
 */

#include <stdio.h>
#include <stdlib.h>
#include "../h/es.h"

int longueur=0;
unsigned char code=0;

/*
 * lire un fichier et mettre les symboles dans le tabAjouts
 */
ajout* lireFichier_C(FILE* bit_stream_in){ 
	unsigned char ch;
	ajout* tableau=(ajout*)calloc(LMAX, sizeof(ajout)); 
	listeSP lsp=NULL;
	
	while(!feof(bit_stream_in)){   
		int i;
		int found=0;
		ch=fgetc(bit_stream_in);

		for(i=0; !found && i<LMAX;i++){  
			if(tableau[i]!=NULL){
				if(tableau[i]->tete->symbole==ch){   
					(tableau[i]->tete->poids)++;
					tableau[i]->poidsSomme=tableau[i]->tete->poids;
					found=1;
				}
			}
			else{
				lsp=newLSP(ch,1,NULL);
				tableau[i]=newAjout(lsp->poids, 1, lsp);
				found=1;
			}	
		}	
	}
	trierTabAjouts(tableau);
	return tableau;
}

/*
 * chercher le code correspondant au char donne
 */
void chercherCode(unsigned char ch, listeSC lsc){
	listeSC courant=NULL;
	int found=0;
	for(courant=lsc; courant!=NULL && !found; courant=courant->suivant){
		if(courant->symbole==ch){
			code=courant->code;		
			longueur=courant->longueur;
			found=1;
		}
	}
}

/*
 * ecrire la listeSC dans le flux
 */
void ecrireLSC(listeSC lsc, binio_t output){
	listeSC courant=NULL;
	binio_unsigned_write(output, ((binio_long_t)'<')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'L')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'S')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'C')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'>')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	for(courant=lsc; courant!=NULL; courant=courant->suivant){
		binio_unsigned_write(output, ((binio_long_t)courant->symbole)<<(sizeof(binio_long_t)-1)*8, 8, 0);
		binio_unsigned_write(output, ((binio_long_t)courant->code)<<(sizeof(binio_long_t)-1)*8, 8, 0);
	}
	binio_unsigned_write(output, ((binio_long_t)'<')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'/')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'L')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'S')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'C')<<(sizeof(binio_long_t)-1)*8, 8, 0);
	binio_unsigned_write(output, ((binio_long_t)'>')<<(sizeof(binio_long_t)-1)*8, 8, 0);
}

/*
 * ecrire un fichier compresse
 */
void ecrireFichier_C(FILE* input, listeSC lsc, binio_t output){
	ecrireLSC(lsc, output);
	while(!feof(input)){
		unsigned char ch=fgetc(input);
		chercherCode(ch, lsc);
		binio_unsigned_write(output, ((binio_long_t)code)<<(sizeof(binio_long_t)*8-longueur), longueur, 0);
	}
}

/*
 * compresser un fichier
 */
void compresser(FILE* input, binio_t output){
	listeSC lsc=NULL;
	listeSL lsl=NULL;
	int* tabLN;
	int lMax;
	
	lsl=package(lireFichier_C(input));
	tabLN=toTabLN(lsl);
	lMax=recupererDernier(lsl);
	lsc=toLSC(lsl, tabLN, lMax);
	ecrireFichier_C(input, lsc, output);
}

/*
 * decompresser un fichier
 */
void decompresser(binio_t input, FILE* output){
	printf("Cette fonction n'est pas encore faite.\n");
}

/*
 * utilisation du programme
 */
void help(){
	printf("\nUtilisation:\n");
	printf("[nom d'app] [-C pour compresser|-D pour decompresser] [fichier source] [fichier destinataire]\n\n");
	exit(0);
}
